import type { FC, ReactNode } from 'react'
import React, { memo, useEffect, useState } from 'react'
import {
  Button,
  Card,
  Col,
  Input,
  InputNumber,
  Row,
  Space,
  Switch,
  theme
} from 'antd'
import { ConfigWrapper } from './style'
import {
  getSensitiveConfig,
  getSensitiveWordTestRes,
  reqRefreshConfig,
  reqUpdateSensitiveConfig
} from '@/service/module/main/system/update-config'

const { useToken } = theme

interface IProps {
  children?: ReactNode
}

const data = [
  ['ignoreCase', '忽略大小写'],
  ['ignoreWidth', '忽略半角圆角'],
  ['ignoreNumStyle', '忽略数字的写法'],
  ['ignoreChineseStyle', '忽略中文的书写格式'],
  ['ignoreEnglishStyle', '忽略英文的书写格式'],
  ['ignoreRepeat', '忽略重复词'],
  ['enableEmailCheck', '启用邮箱检测'],
  ['enableUrlCheck', '启用链接检测'],
  ['enableNumCheck', '启用数字检测']
]

const Config: FC<IProps> = (props) => {
  // 通过 useToken 获取 token 值
  const { token } = useToken()
  // 用于存储敏感词的配置信息
  const [sensitiveConfig, setSensitiveConfig] = useState<any>({})
  // 存储当前选中的敏感词配置 ID
  const [sensitiveWordConfigId, setSensitiveWordConfigId] = useState(0)
  // 存储数字检测长度
  const [numCheckLen, setNumCheckLen] = useState(0)
  // 存储测试文本
  const [testText, setTestText] = useState('')
  // 存储测试结果
  const [testRes, setTestRes] = useState<any>({})

  // 获取敏感词配置信息并设置状态
  const fetchSensitiveData = async () => {
    // 调用 getSensitiveConfig 方法获取配置信息
    const res = await getSensitiveConfig()
    // 将返回值中的 sensitiveWordConfigId 和 numCheckLen 属性提取出来
    const { sensitiveWordConfigId, numCheckLen, ...newSensitiveConfig } =
      res.data
    // 将敏感词配置信息和相关属性分别设置为对应的状态
    setSensitiveConfig(newSensitiveConfig)
    setSensitiveWordConfigId(sensitiveWordConfigId)
    setNumCheckLen(numCheckLen)
  }

  // 处理更新配置以及更新的后续操作
  const handleUpdateConfig = async (params: any) => {
    // 更新配置
    await reqUpdateSensitiveConfig(params)
    // 重新请求页面配置数据
    await fetchSensitiveData()
    // 根据上面更新的配置，去刷新整个系统的数据
    await reqRefreshConfig()
  }

  // 第一次进入页面获取配置并设置默认状态
  useEffect(() => {
    fetchSensitiveData()
  }, [])

  // 切换任意开关触发的回调
  const onSwitchChange = (checked: boolean, index: number) => {
    // 获取 ['ignoreCase', '忽略大小写']这样的item
    const item = data[index]
    // 再获取到字段名'ignoreCase'
    const prop = item[0]
    // 整理参数
    const params = { [prop]: checked, sensitiveWordConfigId }
    handleUpdateConfig(params)
  }

  // 数字输入框改变触发的回调
  const onNumChange = (value: any) => {
    setNumCheckLen(value)
  }

  // 点击数字输入框右边的确定按钮触发的回调
  const onCheckNumLenClick = () => {
    // 整理参数
    const params = { numCheckLen: numCheckLen, sensitiveWordConfigId }
    handleUpdateConfig(params)
  }

  // 测试按钮的回调
  const handleTextTest = async () => {
    const res = await getSensitiveWordTestRes(testText)
    setTestRes(res.data)
  }

  // 渲染页面
  return (
    <ConfigWrapper>
      {/*头部按钮区域*/}
      <Row>
        {data.map((item, index) => (
          <Col key={item[0]} span={6} className="col">
            <Button
              size="small"
              style={{ color: token.colorPrimary }}
              type="link"
            >
              {/*渲染按钮文本*/}
              {item[1]}
            </Button>
            <Switch
              checked={sensitiveConfig[item[0]]}
              // 切换开关
              onChange={(checked) => onSwitchChange(checked, index)}
            />
          </Col>
        ))}
        {/*数字检测长度区域，当 enableNumCheck 为 true 时才会显示*/}
        {sensitiveConfig['enableNumCheck'] && (
          <Col span={18} className="col">
            <Button style={{ color: token.colorPrimary }} type="link">
              数字检查长度
            </Button>
            {/*设置数字长度*/}
            <InputNumber
              value={numCheckLen}
              size="small"
              min={5}
              max={19}
              onChange={onNumChange}
            />
            {/*触发数字长度检测事件*/}
            <Button type="primary" size="small" onClick={onCheckNumLenClick}>
              确定
            </Button>
          </Col>
        )}
      </Row>
      {/*测试区域*/}
      <Card className="card" size="small" title="敏感词测试">
        {/*输入框和测试按钮*/}
        <Space.Compact style={{ width: '100%' }}>
          <Input
            value={testText}
            onChange={(e) => setTestText(e.target.value)}
            placeholder="请输入要测试的文本"
          />
          <Button type="primary" onClick={handleTextTest}>
            测试
          </Button>
        </Space.Compact>
        {/*展示测试结果*/}
        {Object.keys(testRes).length > 0 && (
          <div className="result-area">
            <p>测试结果:{testRes.isContain ? '包含' : '不包含'}</p>
            {testRes?.resultList?.map((item: any, index: number) => (
              <div key={index} className="text-item">
                <span>敏感词：{item.word}</span>
                <span>开始索引：{item.startIndex}</span>
                <span>结束索引：{item.endIndex}</span>
              </div>
            ))}
          </div>
        )}
      </Card>
    </ConfigWrapper>
  )
}

export default memo(Config)
